#	jay skeleton for Java

#	character in column 1 determines outcome...
#		# is a comment
#		. is copied
#		t is copied as //t unless -t is set
#	other lines are interpreted to call jay procedures
 version	Java 1.1.0 (c) 2002-2006 ats@cs.rit.edu / Modified for Semagia MQL
.
 prolog		## %{ ... %} prior to the first %%
.  // %token constants
 tokens	public static final int
.
.  /** number of final state.
.    */
 yyFinal	protected static final int yyFinal =
.
.  /** parser tables.
.      Order is mandated by <i>jay</i>.
.    */
.  protected static final short[] yyLhs = {
 yyLhs
.    }, yyLen = {
 yyLen
.    }, yyDefRed = {
 yyDefRed
.    }, yyDgoto = {
 yyDgoto
.    }, yySindex = {
 yySindex
.    }, yyRindex = {
 yyRindex
.    }, yyGindex = {
 yyGindex
.    }, yyTable = {
 yyTable
.    }, yyCheck = {
 yyCheck
.    };
.
.  /** maps symbol value to printable name.
.      @see #yyExpecting
.    */
.  protected static final String[] yyNames = {
 yyNames-strings
.    };
.
t  /** printable rules for debugging.
t    */
t  protected static final String [] yyRule = {
 yyRule-strings
t    };
t
t  /** debugging support, requires the package <tt>jay.yydebug</tt>.
t      Set to <tt>null</tt> to suppress debugging messages.
t    */
t  protected jay.yydebug.yyDebug yydebug;
t
t  /** index-checked interface to {@link #yyNames}.
t      @param token single character or <tt>%token</tt> value.
t      @return token name or <tt>[illegal]</tt> or <tt>[unknown]</tt>.
t    */
t  public static final String yyName (int token) {
t    if (token < 0 || token > yyNames.length) return "[illegal]";
t    String name;
t    if ((name = yyNames[token]) != null) return name;
t    return "[unknown]";
t  }
t
.  /** thrown for irrecoverable syntax errors and stack overflow.
.      Nested for convenience, does not depend on parser class.
.    */
.  @SuppressWarnings("serial")
.  public static class yyException extends java.lang.Exception {
.    public yyException (String message) {
.      super(message);
.    }
.  }
.
.  /** must be implemented by a scanner object to supply input to the parser.
.      Nested for convenience, does not depend on parser class.
.    */
.  public interface yyInput {
.
.    /** move on to next token.
.        @return <tt>false</tt> if positioned beyond tokens.
.        @throws IOException on input error.
.      */
.    boolean advance () throws java.io.IOException, com.semagia.mql.MQLException;
.
.    /** classifies current token.
.        Should not be called if {@link #advance()} returned <tt>false</tt>.
.        @return current <tt>%token</tt> or single character.
.      */
.    int token ();
.
.    /** associated with current token.
.        Should not be called if {@link #advance()} returned <tt>false</tt>.
.        @return value for {@link #token()}.
.      */
.    Object value ();
.
.    /**
.     * Returns the current line.
.     */
.    int getLine();
.
.    /**
.     * Returns the current column.
.     */
.    int getColumn();
.  }
.
t  /** simplified error message.
t      @see #yyerror(java.lang.String, java.lang.String[])
t    */
t  public void yyerror (String message) {
t    yyerror(message, null);
t  }
.
.  /** (syntax) error message.
.      Can be overwritten to control message format.
.      @param message text to be displayed.
.      @param expected list of acceptable tokens, if available.
.    */
.  public void yyerror (yyInput lexer, String[] expected) throws com.semagia.mql.MQLException {
.     final StringBuffer msg = new StringBuffer("Syntax error. ");
.     if (expected != null && expected.length > 0) {
.         msg.append("Expecting: [");
.         for(int i=0; i<expected.length; ++i) {
.             msg.append(" ").append(expected[i]);
.         }
.         msg.append(" ] ");
.     }
.     String tokenName = null;
.     try { tokenName = tokenToName(lexer.token()); } catch (ArrayIndexOutOfBoundsException ex) {}
.     msg.append("Got: ").append(tokenName).append(", value: '").append(lexer.value()).append("' "); 
.     msg.append("Line: ").append(lexer.getLine()).append(" Column: ").append(lexer.getColumn());
.     throw new com.semagia.mql.MQLParseException(msg.toString(), lexer.getLine(), lexer.getColumn());
.  }
.
.  /** computes list of expected tokens on error by tracing the tables.
.      @param state for which to compute the list.
.      @return list of token names.
.    */
.  protected String[] yyExpecting (int state) {
.    int token, n, len = 0;
.    boolean[] ok = new boolean[yyNames.length];
.
.    if ((n = yySindex[state]) != 0)
.      for (token = n < 0 ? -n : 0;
.           token < yyNames.length && n+token < yyTable.length; ++ token)
.        if (yyCheck[n+token] == token && !ok[token] && yyNames[token] != null) {
.          ++ len;
.          ok[token] = true;
.        }
.    if ((n = yyRindex[state]) != 0)
.      for (token = n < 0 ? -n : 0;
.           token < yyNames.length && n+token < yyTable.length; ++ token)
.        if (yyCheck[n+token] == token && !ok[token] && yyNames[token] != null) {
.          ++ len;
.          ok[token] = true;
.        }
.
.    String result[] = new String[len];
.    for (n = token = 0; n < len;  ++ token)
.      if (ok[token]) result[n++] = tokenToName(token);
.    return result;
.  }
.
.   /**
.    * Translates a token to a name.
.    */
.   protected String tokenToName(final int token) {
.       return yyNames[token];
.   }
.
.
.  /** the generated parser, with debugging messages.
.      Maintains a dynamic state and value stack.
.      @param yyLex scanner.
.      @param yydebug debug message writer implementing <tt>yyDebug</tt>, or <tt>null</tt>.
.      @return result of the last reduction, if any.
.      @throws yyException on irrecoverable parse error.
.    */
.  public Object yyparse (yyInput yyLex, Object yydebug)
.				throws java.io.IOException, yyException, com.semagia.mql.MQLException {
t    this.yydebug = (jay.yydebug.yyDebug)yydebug;
.    return yyparse(yyLex);
.  }
.
.  /** initial size and increment of the state/value stack [default 256].
.      This is not final so that it can be overwritten outside of invocations
.      of {@link #yyparse}.
.    */
.  protected int yyMax;
.
.  /** executed at the beginning of a reduce action.
.      Used as <tt>$$ = yyDefault($1)</tt>, prior to the user-specified action, if any.
.      Can be overwritten to provide deep copy, etc.
.      @param first value for <tt>$1</tt>, or <tt>null</tt>.
.      @return first.
.    */
.  protected Object yyDefault (Object first) {
.    return first;
.  }
.
.  /** the generated parser.
.      Maintains a dynamic state and value stack.
.      @param yyLex scanner.
.      @return result of the last reduction, if any.
.      @throws yyException on irrecoverable parse error.
.    */
.  @SuppressWarnings("unchecked")
.  public Object yyparse (yyInput yyLex) throws java.io.IOException, yyException, com.semagia.mql.MQLException {
.    if (yyMax <= 0) yyMax = 256;			// initial size
.    int yyState = 0, yyStates[] = new int[yyMax];	// state stack
.    Object yyVal = null, yyVals[] = new Object[yyMax];	// value stack
.    int yyToken = -1;					// current input
.    int yyErrorFlag = 0;				// #tokens to shift
.
 local		## %{ ... %} after the first %%

.    yyLoop: for (int yyTop = 0;; ++ yyTop) {
.      if (yyTop >= yyStates.length) {			// dynamically increase
.        int[] i = new int[yyStates.length+yyMax];
.        System.arraycopy(yyStates, 0, i, 0, yyStates.length);
.        yyStates = i;
.        Object[] o = new Object[yyVals.length+yyMax];
.        System.arraycopy(yyVals, 0, o, 0, yyVals.length);
.        yyVals = o;
.      }
.      yyStates[yyTop] = yyState;
.      yyVals[yyTop] = yyVal;
t      if (yydebug != null) yydebug.push(yyState, yyVal);
.
.      yyDiscarded: for (;;) {	// discarding a token does not change stack
.        int yyN;
.        if ((yyN = yyDefRed[yyState]) == 0) {	// else [default] reduce (yyN)
.          if (yyToken < 0) {
.            yyToken = yyLex.advance() ? yyLex.token() : 0;
t            if (yydebug != null)
t              yydebug.lex(yyState, yyToken, yyName(yyToken), yyLex.value());
.          }
.          if ((yyN = yySindex[yyState]) != 0 && (yyN += yyToken) >= 0
.              && yyN < yyTable.length && yyCheck[yyN] == yyToken) {
t            if (yydebug != null)
t              yydebug.shift(yyState, yyTable[yyN], yyErrorFlag > 0 ? yyErrorFlag-1 : 0);
.            yyState = yyTable[yyN];		// shift to yyN
.            yyVal = yyLex.value();
.            yyToken = -1;
.            if (yyErrorFlag > 0) -- yyErrorFlag;
.            continue yyLoop;
.          }
.          if ((yyN = yyRindex[yyState]) != 0 && (yyN += yyToken) >= 0
.              && yyN < yyTable.length && yyCheck[yyN] == yyToken)
.            yyN = yyTable[yyN];			// reduce (yyN)
.          else
.            switch (yyErrorFlag) {
.  
.            case 0:
.              yyerror(yyLex, yyExpecting(yyState));
t              if (yydebug != null) yydebug.error("syntax error");
.  
.            case 1: case 2:
.              yyErrorFlag = 3;
.              do {
.                if ((yyN = yySindex[yyStates[yyTop]]) != 0
.                    && (yyN += yyErrorCode) >= 0 && yyN < yyTable.length
.                    && yyCheck[yyN] == yyErrorCode) {
t                  if (yydebug != null)
t                    yydebug.shift(yyStates[yyTop], yyTable[yyN], 3);
.                  yyState = yyTable[yyN];
.                  yyVal = yyLex.value();
.                  continue yyLoop;
.                }
t                if (yydebug != null) yydebug.pop(yyStates[yyTop]);
.              } while (-- yyTop >= 0);
t              if (yydebug != null) yydebug.reject();
.              throw new yyException("irrecoverable syntax error");
.  
.            case 3:
.              if (yyToken == 0) {
t                if (yydebug != null) yydebug.reject();
.                throw new yyException("irrecoverable syntax error at end-of-file");
.              }
t              if (yydebug != null)
t                yydebug.discard(yyState, yyToken, yyName(yyToken), yyLex.value());
.              yyToken = -1;
.              continue yyDiscarded;		// leave stack alone
.            }
.        }
.        int yyV = yyTop + 1-yyLen[yyN];
t        if (yydebug != null)
t          yydebug.reduce(yyState, yyStates[yyV-1], yyN, yyRule[yyN], yyLen[yyN]);
.        yyVal = yyDefault(yyV > yyTop ? null : yyVals[yyV]);
.        switch (yyN) {

 actions		## code from the actions within the grammar

.        }
.        yyTop -= yyLen[yyN];
.        yyState = yyStates[yyTop];
.        int yyM = yyLhs[yyN];
.        if (yyState == 0 && yyM == 0) {
t          if (yydebug != null) yydebug.shift(0, yyFinal);
.          yyState = yyFinal;
.          if (yyToken < 0) {
.            yyToken = yyLex.advance() ? yyLex.token() : 0;
t            if (yydebug != null)
t               yydebug.lex(yyState, yyToken,yyName(yyToken), yyLex.value());
.          }
.          if (yyToken == 0) {
t            if (yydebug != null) yydebug.accept(yyVal);
.            return yyVal;
.          }
.          continue yyLoop;
.        }
.        if ((yyN = yyGindex[yyM]) != 0 && (yyN += yyState) >= 0
.            && yyN < yyTable.length && yyCheck[yyN] == yyState)
.          yyState = yyTable[yyN];
.        else
.          yyState = yyDgoto[yyM];
t        if (yydebug != null) yydebug.shift(yyStates[yyTop], yyState);
.        continue yyLoop;
.      }
.    }
.  }
.
 epilog			## text following second %%
